#include <dspSimulator/instruction/sploopd.h>


bool SPLOOPD::checkCondition(std::shared_ptr<DspMachine> dspMachine) {
    return true;
}

void SPLOOPD::loadInstIRIntoJit(llvm::LLVMContext *llvmContext, llvm::Module *module,
                                std::shared_ptr<llvm::IRBuilder<>> irBuilder) {

}

std::shared_ptr<Instruction> SPLOOPD::decode(std::shared_ptr<InstInfo> instInfo, u64 baseCycle) {
    std::shared_ptr<SPLOOPD> sploopd;
    auto dspInstInfo = std::dynamic_pointer_cast<DspInstInfo>(instInfo);
    bool isStandardInst = dspInstInfo->isStandardInstruction();
    if (isStandardInst) {
        auto data = vectorToBitSet<32>(dspInstInfo->getBits());
        if(checkBits<21>(data,2,0b000001110100000000000) && existStandardCondition(data)){
            sploopd = std::make_shared<SPLOOPD>(dspInstInfo->getAddress(),baseCycle);
            sploopd->creg_z = extractBits<4>(data, 28);
            sploopd->ii = extractBits<5>(data,23).to_ulong() + 1;
            sploopd->s = data[1];
            sploopd->p = data[0];
        }
    }else{
        auto data = vectorToBitSet<16>(dspInstInfo->getBits());
        if(data[15] == 0 && checkBits<4>(data,10,0b0011) && checkBits<7>(data,0,0b1100111)){
            sploopd = std::make_shared<SPLOOPD>(dspInstInfo->getAddress(),baseCycle);
            sploopd->isCompactInstruction = true;
            sploopd->compactInstKind = "Uspl";
            sploopd->ii = extractBits<3>(data,7).to_ulong();
            sploopd->ii += extractBits<1>(data,14).to_ulong() << 3;
            sploopd->ii += 1;
            sploopd->p = dspInstInfo->getP();
        }
    }
    return sploopd;
}

void SPLOOPD::executeCustom(std::shared_ptr<TargetMachine> targetMachine, ExecutePhase executePhase) {

}

std::string SPLOOPD::toString() const {
    std::string res;
    res = getStandardConditionString() + " " + m_name + " " + std::to_string(ii);
    return res;
}

std::shared_ptr<DspInstruction> SPLOOPD::clone() {
    return std::make_shared<SPLOOPD>(*this);
}
